package com.tangyanbo.mycontacts.dao;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;

import com.tangyanbo.mycontacts.ContactText;
import com.tangyanbo.mycontacts.UserInfo;
import com.tangyanbo.mycontacts.constants.ContactsContants;

public class ContactsDao {

	private Activity context;
	
	private static final String[] PEOPLE_PROJECTION = new String[] {
		ContactsContants.CONTACT_ID,
		ContactsContants.DISPLAY_NAME,
		Photo.PHOTO_ID};
	
	public ContactsDao(Activity context){
		this.context = context;
	}
	
	public String getMobilePhoneByContactId(String contactId){
		try{
			Cursor mobilePhoneCur = context.managedQuery(ContactsContract.Data.CONTENT_URI,
	    			new String[] {ContactsContract.CommonDataKinds.Phone.NUMBER},
	    			ContactsContract.Data.CONTACT_ID+ "=?" + " AND "
	              + ContactsContract.Data.MIMETYPE + "=? "+" AND "
	              +ContactsContract.CommonDataKinds.Phone.TYPE + "=?",
	            new String[]{contactId,ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE,String.valueOf(ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)}, null);
			if(mobilePhoneCur.moveToFirst()){
	        	return mobilePhoneCur.getString(mobilePhoneCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
	        }
			return null;
		}catch(Exception e){
			e.printStackTrace();
        	throw new RuntimeException("Get mobile phone failed.",e);
		}		
	}
	
	public String getHomePhoneByContactId(String contactId){
		try{
			Cursor homePhoneCur = context.managedQuery(ContactsContract.Data.CONTENT_URI,
	    			new String[] {ContactsContract.CommonDataKinds.Phone.NUMBER},
	    			ContactsContract.Data.CONTACT_ID+ "=?" + " AND "
	              + ContactsContract.Data.MIMETYPE + "=? "+" AND "
	              +ContactsContract.CommonDataKinds.Phone.TYPE + "=?",
	            new String[]{contactId,ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE,
					String.valueOf(ContactsContract.CommonDataKinds.Phone.TYPE_HOME)}, null);
			if(homePhoneCur.moveToFirst()){
	        	return homePhoneCur.getString(homePhoneCur.getColumnIndex(ContactsContants.NUMBER));
	        }
			return null;
		}catch(Exception e){
			e.printStackTrace();
        	throw new RuntimeException("Get home phone failed.",e);
		}		
	}
	
	public List<ContactText> findContactTextList(){
		try{
			ContentResolver contentResolver = context.getContentResolver();
			List<ContactText> contactTextList = new ArrayList<ContactText>();
			Cursor contactCursor = contentResolver.query(
					ContactsContract.Contacts.CONTENT_URI,
					PEOPLE_PROJECTION, null, null, "");
			while(contactCursor.moveToNext()){			
				String displayName = contactCursor.getString(contactCursor.getColumnIndex(ContactsContants.DISPLAY_NAME));
				String contactId = contactCursor.getString(contactCursor.getColumnIndex(ContactsContants.CONTACT_ID));
				long photoId = contactCursor.getLong(contactCursor.getColumnIndex(Photo.PHOTO_ID));
				Bitmap cantactPhoto = null;
				if(photoId>0){
					cantactPhoto = getCantactPhoto(Long.parseLong(contactId));
				}
				String mobilePhone = this.getMobilePhoneByContactId(contactId);
				ContactText contactText = new ContactText();
				contactText.setContactId(contactId);
				contactText.setDisplayName(displayName);
				contactText.setNumber(mobilePhone);
				contactText.setCantactPhoto(cantactPhoto);
				contactTextList.add(contactText);
			}		
			return contactTextList;
		}catch(Exception e){
			e.printStackTrace();
        	throw new RuntimeException("Find contact test list failed.",e);
		}		
	}
	
	
	private Bitmap getCantactPhoto(long contactid) {
		Uri uri = ContentUris.withAppendedId(
				ContactsContract.Contacts.CONTENT_URI, contactid);
		InputStream input = ContactsContract.Contacts
				.openContactPhotoInputStream(context.getContentResolver(), uri);
		return BitmapFactory.decodeStream(input);
	}
	
	public void updateUserInfo(UserInfo userInfo,String contactId){
		try{
			ContentResolver contentResolver = context.getContentResolver();
			ContentValues values = new ContentValues();  
			values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, userInfo.getGivenName());
			contentResolver.update(ContactsContract.Data.CONTENT_URI, values, ContactsContract.Data.CONTACT_ID+"=?" +
					" and "+ContactsContract.Data.MIMETYPE + "=?", new String[]{contactId,ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE}); 
			
			values.clear();
			values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, userInfo.getMobileNumber());
			contentResolver.update(ContactsContract.Data.CONTENT_URI, values, ContactsContract.Data.CONTACT_ID+"=?" +
					" and " + ContactsContract.Data.MIMETYPE + "=?" +
					" and " + ContactsContract.CommonDataKinds.Phone.TYPE + "=?",
					new String[]{contactId,ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE,String.valueOf(ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)});
		}catch(Exception e){
			e.printStackTrace();
        	throw new RuntimeException("Update user failed.",e);
		}		
	}
	
	
	public UserInfo getUserInfo(String contactId){
		try{
			UserInfo userInfo = new UserInfo();
			userInfo.setContactId(contactId);
			ContentResolver contentResolver = context.getContentResolver();
			Cursor nameCursor = contentResolver.query(
					ContactsContract.Data.CONTENT_URI,
					new String[] {StructuredName.DISPLAY_NAME},
					ContactsContract.Data.CONTACT_ID + "=?" + 
					" AND "+ ContactsContract.Data.MIMETYPE + "='" +  ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE + "'",
					new String[]{contactId}, null);
			if (nameCursor.moveToFirst()) {
				String displayName = nameCursor
						.getString(nameCursor
								.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME));
				userInfo.setDisplayName(displayName);
			}	
			userInfo.setMobileNumber(this.getMobilePhoneByContactId(contactId));
			userInfo.setHomeNumber(this.getHomePhoneByContactId(contactId));
			return userInfo;
		}catch(Exception e){
			e.printStackTrace();
        	throw new RuntimeException("Get user failed.",e);
		}
	}
	
	public void saveUserInfo(UserInfo userInfo){        
		try {
			ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
	        ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
	                .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
	                .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
	                .build());

	        ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
	                .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
	                .withValue(ContactsContract.Data.MIMETYPE,
	                        ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
	                .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, userInfo.getDisplayName())
	                .build());
			
	        ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
	                .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
	                .withValue(ContactsContract.Data.MIMETYPE,
	                        ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
	                .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, userInfo.getMobileNumber())
	                .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)
	                .build());
            context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
        } catch (Exception e) {
        	e.printStackTrace();
        	throw new RuntimeException("Save user failed.",e);
        }
	}
	
	public void deleteUserInfo(String contactId) {		
		try {
			String where = ContactsContract.Data._ID + " = ? ";
			String[] params = new String[] { contactId };
			ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
			ops.add(ContentProviderOperation
					.newDelete(ContactsContract.RawContacts.CONTENT_URI)
					.withSelection(where, params).build());
            context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
        } catch (Exception e) {
        	e.printStackTrace();
        	throw new RuntimeException("Delete user failed.",e);
        }
	}

	
	
	
	
	
}
